/**************************************
 *
 *           内核层入口
 *
 *************************************/

#include "Base/SharedData.h"
#include "Business/TaskHandle.h"
#include "Business/PluginManagement.h"

SharedData *kernel_data_ptr_ {nullptr};         // 全局数据指针
KSHandle kernel_shared_data_handle_ {NULL};     // 共享数据句柄

// Task处理回调
KSError __stdcall TaskCallback(void * /*pArgs*/, void * /*pContext*/);

// 计时器回调
KSError __stdcall TimerCallback(void * /*pArgs*/, void * /*pContext*/);

// KRTS资源初始化
extern "C" KSError __declspec(dllexport) __stdcall InitFunction(void *pArgs, void * /*pContext*/)
{
    KS_printK("InitFunction called!\n");
    // 获取全局数据指针
    kernel_data_ptr_ = static_cast<SharedData *>(pArgs);

    // 插件注册
    PluginManagement::GetInstance().RegisterPlugin();

    // 创建一个计时器回调
    KSError error = KS_createCallBack(&kernel_data_ptr_->timer_callback_handle, TimerCallback, nullptr, KSF_DIRECT_EXEC | KSF_SAVE_FPU, 0);
    if (error != KS_OK) { return error; }

    // 创建一个计时器
    error = KS_createTimer(&kernel_data_ptr_->timer_handle, 1000*10*REFRESH_TIME,kernel_data_ptr_->timer_callback_handle, KSF_DIRECT_EXEC);
    if (error != KS_OK) { return error; }

    // 设置任务专用的CPU
    error = KS_setTargetProcessor(kernel_data_ptr_->task_cpu,KSF_NO_FLAGS);
    if (error != KS_OK) { KS_printK("KS_setTargetProcessor failed!\n"); }

    error = KS_createCallBack(&kernel_data_ptr_->task_callback_handle, TaskCallback, nullptr, KSF_DIRECT_EXEC | KSF_SAVE_FPU, 0);
    if (error != KS_OK) { return error; }

    error = KS_setTaskStackSize(0x100000, KSF_NO_FLAGS);
    if (error != KS_OK) { return error; }

    error = KS_createTask(&kernel_data_ptr_->task_handle, kernel_data_ptr_->task_callback_handle, 172, KSF_CUSTOM_STACK_SIZE);
    if (error != KS_OK) { return error; }
    return KS_OK;
}

// KRTS资源析构
extern "C" KSError __declspec(dllexport) __stdcall ExitFunction(void * /*pArgs*/, void * /*pContext*/)
{
    KS_printK("ExitFunction called!\n");
    if (kernel_data_ptr_ == nullptr)
    {
        return KSERROR_FUNCTION_NOT_AVAILABLE;
    }

    // 向任务发出终止信号。
    kernel_data_ptr_->abort = 1;

    // 停止计时
    if (kernel_data_ptr_->timer_handle != NULL)
    {
        KS_stopTimer(kernel_data_ptr_->timer_handle);
        KS_removeTimer(kernel_data_ptr_->timer_handle);
        kernel_data_ptr_->timer_handle = NULL;
    }

    // 插件注册
    PluginManagement::GetInstance().UnRegisterPlugin();

    // 删除回调
    if (kernel_data_ptr_->timer_callback_handle != NULL)
    {
        KS_removeCallBack(kernel_data_ptr_->timer_callback_handle);
        kernel_data_ptr_->timer_callback_handle = NULL;
    }

    if (kernel_data_ptr_->task_handle != NULL)
    {
        KS_removeTask(kernel_data_ptr_->task_handle);
    }

    if (kernel_data_ptr_->task_callback_handle != NULL)
    {
        KS_removeCallBack(kernel_data_ptr_->task_callback_handle);
    }

    return KS_OK;
}

// 这是实时任务将运行的函数，并对执行 Task 操作。只有实时任务才应调用 Task 函数。
KSError __stdcall TaskCallback(void * /*pArgs*/, void * /*pContext*/)
{
    // 处理循环，此循环仅在发出中止信号时停止。
    while (true)
    {
        // 等待停止的通知。
        if (kernel_data_ptr_->abort != 0) { break; }

        // Todo 处理 lua
        if (kernel_data_ptr_->script_run_status)
        {
            TaskHandle::OnLuaScript();
            kernel_data_ptr_->script_run_status = false;
        }

        KS_sleepTask(REFRESH_TIME*10*1000);
    }
    return KS_OK;
}

KSError __stdcall TimerCallback(void * /*pArgs*/, void * /*pContext*/)
{
    KS_printK("TimerCallback called!\n");
    return KS_OK;
}

#pragma pack(push, 8)
#include <windows.h>
#pragma pack(pop)

BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD reason, LPVOID pReserved)
{
    return TRUE;
}
